package com.example.springtaskschedule.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;


/**
 * @author liyinfan
 * @date 2019-7-25 16:49:12
 * @Description: 线程池配置类
 */
@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
    private static final Logger logger = LoggerFactory.getLogger(AsyncConfig.class);

    @Value("${egsc.config.task.corePoolSize:1}")
    private Integer corePoolSize;
    @Value("${egsc.config.task.maxPoolSize:1}")
    private Integer maxPoolSize;
    @Value("${egsc.config.task.queueCapacity:1}")
    private Integer queueCapacity;
    @Value("${egsc.config.task.threadNamePrefix:AsyncThread-}")
    private String threadNamePrefix;


    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(60);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(8);
        executor.setThreadNamePrefix(threadNamePrefix);
        executor.setTaskDecorator(mdcTaskDecorator());
        /*executor.setRejectedExecutionHandler();
        默认会抛出RejectedExecutionException*/
        executor.initialize();
        return executor;
    }

    @Bean(name = "test1TaskExecutor")
    public ThreadPoolTaskExecutor test1TaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(60);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(8);
        executor.setThreadNamePrefix("test1TaskExecutor");
        executor.setTaskDecorator(mdcTaskDecorator());
        /*executor.setRejectedExecutionHandler();
        默认会抛出RejectedExecutionException*/
        executor.initialize();
        return executor;
    }

    @Bean
    public MdcTaskDecorator mdcTaskDecorator() {
        return new MdcTaskDecorator();
    }

    /**
     * 初始化默认的线程池 @Async使用
     *
     * @return
     */
    @Bean("asyncExecutor")
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(60);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(8);
        executor.setThreadNamePrefix("default-t");
        executor.setTaskDecorator(mdcTaskDecorator());
        /*executor.setRejectedExecutionHandler();
        默认会抛出RejectedExecutionException*/
        executor.initialize();
        return executor;
    }

    /**
     * 如果本方法返回为空，则使用 SimpleAsyncUncaughtExceptionHandler 只打印异常信息
     *
     * @return
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return super.getAsyncUncaughtExceptionHandler();
    }

}
